package com.tan.lbs.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Xml;

import com.tan.lbs.NPCGreetingActivity;
import com.tan.lbs.NPCTalkingActivity;
import com.tan.lbs.dao.NPCDAO;
import com.tan.lbs.entity.DialogNode;
import com.tan.lbs.entity.DialogNodeOrder;
import com.tan.lbs.entity.GameHeader;
import com.tan.lbs.entity.NPC;
import com.tan.lbs.util.Constants;
import com.tan.lbs.util.SQLiteDatabaseHelper;

public class NPCDAOImpl implements NPCDAO {

	private Context context;
	
	public static final int MAX_DIALOG_BRANCH  = 4;

	public NPCDAOImpl(Context context) {
		this.context = context;
	}

	@Override
	public List<NPC> retrieveNPCs(String gameID) {
		List<NPC> npcs = null;
		NPC npc = null;
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(
					context.getResources().getAssets()
							.open("gameFiles/" + gameID + "/npc.xml"), "UTF-8");

			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {
				switch (event) {
				case XmlPullParser.START_DOCUMENT:
					npcs = new ArrayList<NPC>();
					break;
				case XmlPullParser.START_TAG:
					if ("npc".equals(parser.getName())) {
						npc = new NPC();
					}
					if (npc != null) {
						if ("npcID".equals(parser.getName())) {
							npc.setNpcID(parser.nextText());
						} else if ("greeting".equals(parser.getName())) {
							npc.setGreeting(parser.nextText());
						} else if ("name".equals(parser.getName())) {
							npc.setName(parser.nextText());
						} else if ("iconID".equals(parser.getName())) {
							npc.setIconID(parser.nextText());
						} else if ("chattable".equals(parser.getName())) {
							npc.setChattable(parser.nextText());
						} else if ("figureID".equals(parser.getName())) {
							npc.setFigureID(parser.nextText());
						} else if ("dialogID".equals(parser.getName())) {
							npc.setDialogID(parser.nextText());
						} else if ("lat".equals(parser.getName())) {
							npc.setLat(Float.parseFloat(parser.nextText()));
						} else if ("lng".equals(parser.getName())) {
							npc.setLng(Float.parseFloat(parser.nextText()));
						}
					}
					break;
				case XmlPullParser.END_TAG:
					if ("npc".equals(parser.getName())) {
						npcs.add(npc);
						npc = null;
					}
					break;
				}
				event = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return npcs;
	}

	@Override
	public NPC readNPC(String npcID, String gameID) {
		NPC npc = null;
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(
					context.getResources().getAssets()
							.open("gameFiles/" + gameID + "/npc.xml"), "UTF-8");

			int event = parser.getEventType();
			String searchID;
			boolean found = false;
			while (event != XmlPullParser.END_DOCUMENT) {
				if (event == XmlPullParser.START_TAG) {
					if ("npcID".equals(parser.getName())) {
						searchID = parser.nextText();
						if (searchID.equals(npcID)) {
							npc = new NPC();
							npc.setNpcID(npcID);
							found = true;
						}
					} else if ("greeting".equals(parser.getName()) && found) {
						npc.setGreeting(parser.nextText());
					} else if ("name".equals(parser.getName()) && found) {
						npc.setName(parser.nextText());
					} else if ("iconID".equals(parser.getName()) && found) {
						npc.setIconID(parser.nextText());
					} else if ("chattable".equals(parser.getName()) && found) {
						npc.setChattable(parser.nextText());
					} else if ("figureID".equals(parser.getName())&& found) {
						npc.setFigureID(parser.nextText());
					} else if ("dialogID".equals(parser.getName())&& found) {
						npc.setDialogID(parser.nextText());
					} else if ("lat".equals(parser.getName())&& found) {
						npc.setLat(Float.parseFloat(parser.nextText()));
					} else if ("lng".equals(parser.getName())&& found) {
						npc.setLng(Float.parseFloat(parser.nextText()));
					}
				} else if (event == XmlPullParser.END_TAG && found && "npc".equals(parser.getName())) {
					break;
				}
				event = parser.next();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return npc;
	}

	@Override
	public DialogNode readDialogNode(String dialogNodeID, String gameID) {
		DialogNode dialogNode = null;
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(
					context.getResources().getAssets()
							.open("gameFiles/" + gameID + "/dialognode.xml"), "UTF-8");

			int event = parser.getEventType();
			String searchID;
			boolean found = false;
			while (event != XmlPullParser.END_DOCUMENT) {
				if (event == XmlPullParser.START_TAG) {
					if ("dialogNodeID".equals(parser.getName())) {
						searchID = parser.nextText();
						if (searchID.equals(dialogNodeID)) {
							dialogNode = new DialogNode();
							dialogNode.setDialogNodeID(dialogNodeID);
							found = true;
						}
					} else if ("name".equals(parser.getName()) && found) {
						dialogNode.setName(parser.nextText());
					} else if ("containedMediaID".equals(parser.getName()) && found) {
						dialogNode.setContainedMediaID(parser.nextText());
					} else if ("interactionType".equals(parser.getName()) && found) {
						dialogNode.setInteractionType(parser.nextText());
					} else if ("nodeType".equals(parser.getName())&& found) {
						dialogNode.setNodeType(parser.nextText());
					} else if ("displayText".equals(parser.getName())&& found) {
						dialogNode.setDisplayText(parser.nextText());
					} 
				} else if (event == XmlPullParser.END_TAG && found && "dialognode".equals(parser.getName())) {
					break;
				}
				event = parser.next();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return dialogNode;
	}

	@Override
	public List<DialogNodeOrder> retrieveAdjacentDialogNodeOrder(
			String fromDialogNodeID, String gameID) {
		List<DialogNodeOrder> dialogNodeOrders = null;
		DialogNodeOrder dialogNodeOrder = null;
		int collectDialogNodeNum = 0;
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(
					context.getResources().getAssets()
							.open("gameFiles/" + gameID + "/dialognodeorder.xml"), "UTF-8");

			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {
				switch (event) {
				case XmlPullParser.START_DOCUMENT:
					dialogNodeOrders = new ArrayList<DialogNodeOrder>();
					break;
				case XmlPullParser.START_TAG:
					if ("dialogNodeOrder".equals(parser.getName())) {
						dialogNodeOrder = new DialogNodeOrder();
					}
					if (dialogNodeOrder != null) {
						if ("fromNodeID".equals(parser.getName())) {
							dialogNodeOrder.setFromNodeID(parser.nextText());
						} else if ("toNodeID".equals(parser.getName())) {
							dialogNodeOrder.setToNodeID(parser.nextText());
						} else if ("answer".equals(parser.getName())) {
							dialogNodeOrder.setAnswer(parser.nextText());
						} else if ("answerOrder".equals(parser.getName())) {
							dialogNodeOrder.setAnswerOrder(Integer.valueOf(parser.nextText()));
						} 
					}
					break;
				case XmlPullParser.END_TAG:
					if ("dialogNodeOrder".equals(parser.getName())) {
						if(dialogNodeOrder!= null && dialogNodeOrder.getFromNodeID().equals(fromDialogNodeID)) {
							dialogNodeOrders.add(dialogNodeOrder);
							collectDialogNodeNum++;
						}
					}
					break;
				}
				event = parser.next();
				//For early break
				if(collectDialogNodeNum == MAX_DIALOG_BRANCH) break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dialogNodeOrders;
	}

	@Override
	public String readNPCStatus(String npcID) {
		SQLiteDatabaseHelper dbHelper = new SQLiteDatabaseHelper(
				context, Constants.LOCAL_DB_NAME);
		 SQLiteDatabase db = dbHelper.getReadableDatabase();
		
		Cursor cursor = db.query("npc", new String[] { "npcID",
				"status" }, "npcID=?",
				new String[] { npcID }, null, null,
				null);
		cursor.moveToNext();
		String statusReturn = cursor.getString(cursor.getColumnIndex("status"));
		db.close();
		return statusReturn;
	}

	@Override
	public void updateNPCStatus(String npcID, String status) {
		SQLiteDatabaseHelper dbHelper = new SQLiteDatabaseHelper(
				context, Constants.LOCAL_DB_NAME);
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put("status", status);
		db.update("npc", values, "npcID=?", new String[]{npcID});
		db.close();
	}

}
